using System.IO;
using UnityEngine;
using XLua;
using System;
using UnityEngine.SceneManagement;

namespace SgsUI
{
    [LuaCallCSharp]
    public class LuaManager : Singleton<LuaManager>
    {
        public const string luaAssetbundleAssetName = "Lua";
        public const string luaScriptsFolder = "../Lua";
        public const string commonMainScriptName = "Common.Main";
        public const string gameMainScriptName = "GameMain";
        public LuaEnv luaEnv = null;

        LuaFunction luaEventFunc = null;

        public bool HasGameStart
        {
            get;
            protected set;
        }

        public override void Init()
        {
            base.Init();
            
            InitLuaEnv();

            // SceneManager.sceneLoaded += OnSceneLoaded;
            // SceneManager.sceneUnloaded += OnSceneUnLoaded;
        }

        public void Reload()
        {
            if(luaEnv != null)
            {
                luaEnv.Dispose();
                luaEnv = null;
            }
            InitLuaEnv();
        }

        void print(object obj)
        {
            Debug.Log(obj);
        }

        public void SendLuaEvent(params object[] args)
        {
            if(luaEnv != null && luaEventFunc != null)
            {
                try
                {
                    luaEventFunc.Call(args);
                }
                catch ( Exception ex)
                {
                    print("luaEventFunc err : " + ex.Message + "\n" + ex.StackTrace);
                }
            }
        }

        void InitLuaEnv()
        {
            luaEnv = new LuaEnv();
            // luaEnv.AddBuildin("protobuf.c", XLua.LuaDLL.Lua.LoadPBC);
            
            HasGameStart = false;
            if (luaEnv != null)
            {
                // if(Assets.Updatable)
                //     luaEnv.AddLoader(ReadBytesFromAssetBundle);
                // else
                luaEnv.AddLoader(CustomLoader);
            }
            else
            {
                Debug.Log("InitLuaEnv null!!!");
            }

            StartGame();
            Debug.Log("InitializeOnLoadMethod called.");
        }

        // private static byte[] ReadBytesFromAssetBundle(ref string filepath)
        // {
        //     var path = "Assets/Resources/Lua/" + filepath.Replace(".","/") + ".lua";
        //     var asset = Asset.Load(path, typeof(TextAsset)); 
        //     TextAsset ta = asset.asset as TextAsset;
        //     return ta.bytes;
        // }

        private static byte[] CustomLoader(ref string filepath)
        {
            string scriptPath = string.Empty;
            filepath = filepath.Replace(".","/") + ".lua";

            int temp = 1;
            if(temp==1)
            {
                scriptPath = Path.Combine(Application.dataPath,luaScriptsFolder);
                scriptPath = Path.Combine(scriptPath,filepath);

                return GameUtility.SafeReadAllBytes(scriptPath);
            }

            Debug.Log("Load lua script failed : " + scriptPath + ", You should preload lua assetbundle first!!!");
            return null;
        }

        void Update()
        {
            SendLuaEvent("SendLuaEvent",Time.deltaTime,Time.unscaledDeltaTime);
        }

        public void StartGame()
        {
            if (luaEnv != null)
            {
                LoadScript(gameMainScriptName);
                SafeDoString("GameMain.Start()");

                luaEventFunc = luaEnv.Global.Get<LuaFunction>("LuaEventFunc");

                HasGameStart = true;
            }
        }

        void LoadScript(string scriptName)
        {
            SafeDoString(string.Format("require('{0}')", scriptName));
        }

        public void SafeDoString(string scriptContent)
        {
            if (luaEnv != null)
            {
                try
                {
                    luaEnv.DoString(scriptContent);
                }
                catch (System.Exception ex)
                {
                    string msg = string.Format("xLua exception : {0}\n {1}", ex.Message, ex.StackTrace);
                    Debug.Log(msg, null);
                }
            }
        }
    }
}